const express = require("express");
const util = require("../common/util");
const ItemDB = require("../model/db/item");

/**
 * 获取指定ID的物品
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function find(req, res) {
  (async function () {
    const db = ItemDB.getInstance();
    const result = await db.find(req.params.itemId);
    util.logFormat(`获取【${req.params.itemId}】物品信息：%O`, result);
    res.json(util.FormatJSONData(200, `获取物品信息【${req.params.itemId}】成功`, result));
  })();
}

/**
 * 获取物品列表
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function findAll(req, res) {
  (async function () {
    const limit = req.query.limit ? parseInt(req.query.limit) : -1;
    const offset = req.query.offset ? parseInt(req.query.offset) : -1;
    const userId = req.session.user.id;

    const db = ItemDB.getInstance();
    const result = await db.findAll(userId, limit, offset);

    //await db.close();
    util.logFormat(
      `获取【limit=${limit}&offset=${offset}】物品列表信息：%O`,
      result
    );  
    res.json(util.FormatJSONData(200, `获取物品列表信息成功`, result));
  })();
}

/**
 * 获取个人物品列表
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function findSelfAll(req, res) {
  (async function () {
    const limit = req.query.limit ? parseInt(req.query.limit) : -1;
    const offset = req.query.offset ? parseInt(req.query.offset) : -1;
    const userId = req.session.user.id;

    console.log(userId);
    const db = ItemDB.getInstance();
    const result = await db.findSelfAll(userId, limit, offset);

    //await db.close();
    util.logFormat(
      `获取【limit=${limit}&offset=${offset}】物品列表信息：%O`,
      result
    );
    res.json(util.FormatJSONData(200, `获取物品列表信息成功`, result));
  })();
}



/**  
 * 新增物品  
 * @param {express.Request} req 请求  
 * @param {express.Response} res 响应  
 */
async function add(req, res) {
    const orderId = await util.generateUniqueOrderNumber(req.session.user.phone_number);
    console.log(orderId);
    try {
      const item = {
        name: req.body.name,
        description: req.body.description,
        category: req.body.category,
        orderId: orderId,
        // storageTime: new Date(req.body.storageTime || Date.now()).toISOString().slice(0, 19).replace('T', ' '),
        ownerId: req.session.user.id,
        quantity: req.body.quantity,
        barcode: req.body.barcode,
        imagePath: req.body.imagePath,
        retrieveTime: req.body.retrieveTime,
      };

      const db = ItemDB.getInstance();  

      const lastID = await db.add(item);

      util.log(`新增物品信息：lastID=${lastID}`);

      res.json(util.FormatJSONData(201, `新增物品信息成功`, { lastID }));
    } catch (error) {
      // 处理错误  
      util.err(error);
      res.status(500).json(util.FormatJSONData(500, '服务器内部错误', error));
    }
}
/**
 * 更新物品
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function update(req, res) {
  try {
    const item = {
      id: req.params.itemId,
      name: req.body.name,
      description: req.body.description,
      category: req.body.category,
      quantity: req.body.quantity,
      imagePath: req.body.imagePath,
    };

    const db = ItemDB.getInstance();
    let items = await db.find(req.params.itemId);
    if (!items) {
      res.status(404).json(util.FormatJSONData(404, `物品不存在`, {}));
      return;
    }
    const ownerId = items[0].owner_id; // 确保items是一个数组
    if (ownerId !== req.session.user.id && req.session.user.role !== 1) {
      res.status(403).json(util.FormatJSONData(403, `无权限修改物品信息`, {}));
      return;
    }
    const changes = await db.update(item);

    //await db.close();
    util.log(`修改物品信息：changes=${changes}`);
    res.status(200).json(util.FormatJSONData(200, `更新物品信息成功`, { changes }));
  } catch (error) {
    // 在这里处理错误
    util.log(`修改物品信息失败: ${error.message || error.toString()}`);
    res.status(500).json(util.FormatJSONData(500, `修改物品失败`, { error: error.message || error.toString() }));
  }
}


async function remove(req, res) {  
    try {  
      // 假设 itemId 是通过请求体传递的  
      const itemId = req.params.itemId;  
  
      // 这里可以添加更多的验证逻辑，例如检查 itemId 是否为数字、是否在允许的范围内等  
      if (Number.isNaN(itemId)) {  
        throw new Error('Invalid itemId');  
      }  
  
      const db = ItemDB.getInstance();  
      const changes = await db.remove(itemId);  
  
      // 检查是否实际有记录被删除  
      if (changes === 0) {  
        throw new Error('Item not found');  
      }  
  
      util.log(`删除物品信息：changes=${changes}`);  
      res.json(util.FormatJSONData(204, '删除物品信息成功', { changes }));  
    } catch (err) {  
      // 在这里处理错误，并返回适当的HTTP响应  
      util.log(`删除物品时出错：${err.message}`);  
      res.status(400).json(util.FormatJSONData(400, '删除物品失败', { error: err.message }));  
    }  
}

/**
 * 获取物品总数
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function getCount(req, res) {
    let db = ItemDB.getInstance();
    let count = await db.getCount();
    util.log(`物品总数：${count}`);
    res.json(util.FormatJSONData(200, `获取物品总数成功`, count));

}

/**
 * 获取个人物品总数
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function getSelfCount(req, res) {
    let userId = req.session.user.id;
    let db = ItemDB.getInstance();
    let count = await db.getSelfCount(userId);
    util.log(`个人物品总数：${count}`);
    res.json(util.FormatJSONData(200, `获取个人物品总数成功`, count));
}

async function search(req, res){
      //1.处理输入的数据
      //FIXME：输入数据的正确性校验，一致性校验，完整性校验
      let q = req.query.q;
      let limit = req.query.limit ? req.query.limit : -1;
      let offset = req.query.offset ? req.query.offset : -1;
      //2.访问数据
      let db = ItemDB.getInstance();
      console.log(db);
      let result = await db.search(q,limit, offset);
      
      //3.处理输出数据
      //await db.close():
      util.logFormat(`获取关键字为【${q}】【limit=${limit}&offset=${offset}】书籍信息%O`, result);
      res.json(util.FormatJSONData(200, `获取指定关键字的物品信息列表`, result));
}

/**
 * 批量添加物品
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function batchAdd(req, res) {
    const items = req.body.items;
    const db = ItemDB.getInstance();
    
    for (const item of items) {   
        item.owner_id = req.session.user.id;  
        // 注意这里使用了 await，所以这个函数必须是 async  
        item.orderId = await util.generateUniqueOrderNumber(req.session.user.phone_number);  
        console.log(item.orderId);  
    }  
    //这个不允许用异步方式
    // items.forEach(item => {  
    //   if (!item.ownerId) {  
    //     item.owner_id = req.session.user.id;  
    //     item.order_id = async util.generateUniqueOrderNumber(req.session.user.phone_number);
    //     console.log(item.order_id)
    //   }  
    // });  
    const affectedRows = await db.batchAdd(items);

    util.log(`批量添加物品信息：affectedRows=${affectedRows}`);
    res.json(util.FormatJSONData(201, `批量添加物品信息成功`, { affectedRows }));
}

/**  
 * 批量更新物品  
 * @param {express.Request} req 请求  
 * @param {express.Response} res 响应  
 */  
async function batchUpdate(req, res) {  
  try {  
    const items = req.body.items; 
    const db = ItemDB.getInstance();  
    const updateResults = await db.batchUpdate(items);  
    util.log(`批量更新物品信息：updateResult=${updateResults}`);  
    res.json(util.FormatJSONData(200, `批量更新物品信息成功`, { updateResults}));  
  } catch (error) {  
    // 向客户端返回错误消息  
    res.status(500).json(util.FormatJSONData(500, `批量更新物品信息失败`, error.message));  
  }  
}

/**
 * 批量删除物品
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function batchRemove(req, res) {
    const itemIds = req.body.itemIds;

    const db = ItemDB.getInstance();
    await db.connect();
    const affectedRows = await db.batchRemove(itemIds);

    //await db.close();
    util.log(`批量删除物品信息：affectedRows=${affectedRows}`);
    res.json(util.FormatJSONData(204, `批量删除物品信息成功`, { affectedRows }));
}




/**  
 * 获取物品及其所属用户信息  
 * @param {express.Request} req 请求  
 * @param {express.Response} res 响应  
 */  
async function getItemWithOwner(req, res) {  
    try {  
      const itemId = req.params.itemId;  
      const db = ItemDB.getInstance();  
      const itemWithOwner = await db.getItemWithOwner(itemId);  
  
      // 检查是否找到了物品  
      if (!itemWithOwner || itemWithOwner.length === 0) {  
        // 如果没有找到物品，返回一个 404 响应  
        res.status(404).send('没有找到该物品');  
      } else {  
        // 记录日志  
        util.logFormat(`获取【${itemId}】物品及其所属用户信息：%O`, itemWithOwner);  
  
        // 返回找到的物品及其所有者信息  
        res.json(util.FormatJSONData(200, `获取物品及其所属用户信息成功`, itemWithOwner)); // 注意这里我们取数组的第一个元素，因为通常 query 返回的是一个数组  
      }  
    } catch (err) {  
      // 处理任何可能发生的异常  
      console.error('获取物品及其所属用户信息时发生错误：', err);  
      res.status(500).json(util.FormatJSONData(500, `服务器内部错误`, err.message || '未知错误'));  
    } 
}
/**
 * 获取物品及其所在位置信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function getItemWithLocation(req, res) {
    const itemId = req.params.itemId;

    const db = ItemDB.getInstance();
    const itemWithLocation = await db.getItemWithLocation(itemId);

    util.logFormat(`获取【${itemId}】物品及其所在位置信息：%O`, itemWithLocation);
    res.json(util.FormatJSONData(200, `获取物品及其所在位置信息成功`, itemWithLocation));
}

/**
 * 统计分析
 */

/**
 * 按类别统计物品数量
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function countByCategory(req, res) {
    const db = ItemDB.getInstance();
    const categoryCounts = await db.countByCategory();

    //await db.close();
    util.logFormat(`按类别统计物品数量：%O`, categoryCounts);
    res.json(util.FormatJSONData(200, `按类别统计物品数量成功`, categoryCounts));
}

/**
 * 获取物品存储时间分布
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function getStorageTimeDistribution(req, res) {
    const db = ItemDB.getInstance();
    await db.connect();
    const storageTimeDistribution = await db.getStorageTimeDistribution();

    //await db.close();
    util.logFormat(`物品存储时间分布：%O`, storageTimeDistribution);
    res.json(util.FormatJSONData(200, `获取物品存储时间分布成功`, storageTimeDistribution));
}

/**
 * 获取物品状态分布
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
async function getStatusDistribution(req, res) {
    const db = ItemDB.getInstance();
    await db.connect();
    const statusDistribution = await db.getStatusDistribution();

    //await db.close();
    util.logFormat(`物品状态分布：%O`, statusDistribution);
    res.json(util.FormatJSONData(200, `获取物品状态分布成功`, statusDistribution));
}


module.exports = {
  getSelfCount,
  findAll,
  findSelfAll,
  add,
  update,
  remove,
  getCount,
  search,
  find,
  batchAdd,
  batchUpdate,
  batchRemove,
  getItemWithOwner,
  getItemWithLocation,
  countByCategory,
  getStorageTimeDistribution,
  getStatusDistribution,
};